<template>
    <el-popover
            :visible="state.visible"
            :width="320"
            placement="left"
            trigger="click"
    >
        <template #reference>
            <el-button class="m-2" @click="state.visible = true">
                {{ state.active }}
            </el-button>
        </template>

        <div class="fill-width">

            <el-form
                    ref="bindFormRef"
                    :model="state.form"
                    :rules="rules"
                    label-width="80px"
                    status-icon
            >

                <el-form-item
                        label="字段名称"
                        prop="name"
                >
                    <el-input v-model="state.form.name" placeholder="字段名称"/>
                </el-form-item>

                <el-form-item
                        label="绑定类型"
                        prop="bindName"
                >
                    <el-select
                            v-model="state.form.bindName"
                            class="fill-width"
                            @change="onBindNameChange"
                    >
                        <el-option
                                v-for="item in state.bindType"
                                :key="item.value"
                                :label="item.label"
                                :value="item.value"
                        />
                    </el-select>
                </el-form-item>

                <el-form-item
                        v-if="state.form.bindName == 'BindDict'"
                        label="字典类型"
                        prop="entity"
                >
                    <el-select
                            v-model="state.form.entity"
                            class="fill-width"
                    >
                        <el-option
                                v-for="item in state.dicts"
                                :key="item.value"
                                :label="<any>item.label"
                                :value="item.value"
                        />
                    </el-select>
                </el-form-item>

                <el-form-item
                        v-if="state.form.bindName != 'BindDict'"
                        label="绑定实体"
                        prop="entity"
                >
                    <el-select
                            v-model="state.form.entity"
                            class="fill-width"
                            @change="onEntitySelect"
                    >
                        <el-option
                                v-for="item in api.tableState.dataSource"
                                :key="item.id"
                                :label="<any>item.className"
                                :value="item.id"
                        />
                    </el-select>
                </el-form-item>

                <el-form-item
                        v-if="state.form.bindName == 'BindField' || state.form.bindName == 'BindFieldList'"
                        label="绑定字段"
                        prop="field"
                >
                    <el-select
                            v-model="state.form.field"
                            class="fill-width"
                            @change="onFieldChange"
                    >
                        <el-option
                                v-for="item in state.fields"
                                v-if="state.fields.length>0"
                                :key="item.commentName"
                                :label="<any>item.commentName"
                                :value="item.commentName"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item
                        v-if="state.form.bindName != 'BindDict'"
                        label="condition"
                        prop="conditionValue"
                >
                    <el-input v-model="state.form.conditionValue" placeholder="condition"/>
                </el-form-item>

                <el-form-item class="mb-0">
                    <el-button size="small" type="primary" @click="onSubmit">确定</el-button>
                    <el-button size="small" @click="onClose">关闭</el-button>
                </el-form-item>
            </el-form>
        </div>
    </el-popover>
</template>

<script lang="ts" setup>
import {reactive, ref} from "vue";
import {GenTableApi} from "~/api/system/gen/gen.api";
import {AttachMore} from "~/api/types";
import {FormRules} from "element-plus";
import {GenField, GenVoField} from "~/api/system/gen/types";

interface Form {
    type?: string,
    name?: string,
    bind?: string,
    bindName?: string,
    entity?: string,
    entityClass?: string,
    conditionValue?: string,
    field?: string,
}

interface Props {
    api: GenTableApi;
    field: GenField;
    voFields?: GenVoField[];
}

const props = withDefaults(defineProps<Props>(), {});
const {api, field} = reactive(props);

const bindFormRef = ref();

const rules = reactive<FormRules>({
    name: [{required: true, message: "请输入字段名称", trigger: "blur"}],
    bindName: [{required: true, message: "请选择", trigger: "blur"}],
    entity: [{required: true, message: "请输入bindName", trigger: "blur"}],
});

const emits = defineEmits([
    "update:type",
    "update:name",
    "update:bind",
    "update:bindName",
    "update:entity",
    "update:entityClass",
    "update:conditionValue",
    "update:field",
    "submit",
]);

const state = reactive<{
    visible: boolean
    bindType: any[]
    fields: any[]
    dicts: any[]
    active: "无" | "BindField" | "BindFieldList" | "BindEntity" | "BindEntityList" | "BindDict",
    form: Form,
}>({
    visible: false,
    bindType: [
        {value: "BindField", label: "BindField"},
        {value: "BindFieldList", label: "BindFieldList"},
        {value: "BindEntity", label: "BindEntity"},
        {value: "BindEntityList", label: "BindEntityList"},
        {value: "BindDict", label: "BindDict"},
    ],
    fields: [],
    dicts: [],
    active: "无",
    form: {
        type: undefined,
        name: undefined,
        bind: undefined,
        bindName: undefined,
        entity: undefined,
        entityClass: undefined,
        conditionValue: undefined,
        field: undefined,
    },
});

async function onBindNameChange(e: any) {
    state.form.bind = "com.icesoft.framework.core.binding.annotation." + e;
    if (e == "BindDict") {
        const params: AttachMore = {
            target: "dictionary",
            label: "itemName",
            value: "type",
            condition: {
                parentId: "0",
            },
        };
        const res = await api.attachMore([params]);
        state.dicts = res.data.dictionaryOptions;
        state.form.type = "java.lang.String";
    }
    state.active = e;
    state.form.conditionValue = undefined;
    state.form.entityClass = undefined;
    state.form.entity = undefined;
}

async function onEntitySelect(e: any) {
    state.form.field = undefined;
    state.fields = [];
    const res = await api.load(e);
    state.fields.push({
        commentName: "id",
        name: "id",
        type: "java.lang.String",
    });
    res.data?.fields?.forEach(filed => {
        state.fields.push(filed);
    });
    const entityClass = res.data?.packageName + ".entity." + res.data?.className;
    state.form.entity = res.data?.className;
    state.form.entityClass = entityClass;

    if (state.form.bindName == "BindEntity" || state.form.bindName == "BindEntityList") {
        state.form.conditionValue = "this." + field.name + "=id";
    }

    if (state.form.bindName == "BindField" || state.form.bindName == "BindEntity") {
        state.form.type = entityClass;
    }
    if (state.form.bindName == "BindFieldList" || state.form.bindName == "BindEntityList") {
        state.form.type = "java.util.List<" + entityClass + ">";
    }
    if (state.form.bindName == "BindDict") {
        state.form.type = "java.lang.String";
    }
}

async function onFieldChange(e: any) {
    state.form.conditionValue = "this." + field.name + "=" + state.form.field;
}

async function onSubmit() {
    const values = await bindFormRef.value.validate();
    if (values) {
        emits("update:type", state.form.type);
        emits("update:name", state.form.name);
        emits("update:bind", state.form.bind);
        emits("update:bindName", state.form.bindName);
        emits("update:entity", state.form.entity);
        emits("update:entityClass", state.form.entityClass);
        emits("update:conditionValue", state.form.conditionValue);
        emits("update:field", state.form.field);
        emits("submit", state.form);
        state.visible = false;
    }
}

function onClose() {
    state.visible = false;
}

</script>

<style lang="scss" scoped>

</style>
